<template>
  <div class="app-container">
    <div class="filter-container">
      <el-input
        v-model="search.jobName"
        v-haspermi="['bxy:timingtaskmanager:search']"
        :placeholder="$t('console.enterTaskname')"
        :maxlength="50"
        class="filter-item"
        clearable
        @blur="trim('jobName')"
        @mouseout.native="blurRule($event)"
      />
      <el-button
        v-haspermi="['bxy:timingtaskmanager:search']"
        class="filter-item"
        type="primary"
        icon="el-icon-search"
        @click.native="getTimingTasks"
      >
        {{ $t('common.sousou') }}
      </el-button>
      <!-- TODO (YKX) 暂时不使用新增功能 -->
      <!-- <el-button
        style="float: right;"
        type="primary"
        icon="el-icon-edit"
        @click="newAdd"
      >
        {{ $t('common.newAdd') }}
      </el-button> -->
    </div>

    <el-table
      :data="tasks"
      border
      fit
      highlight-current-row
      style="width: 100%;"
    >
      <el-table-column
        type="index"
        :label="$t('common.num')"
        align="center"
        width="80"
      />
      <el-table-column
        property="jobName"
        :label="$t('console.taskName')"
        align="center"
        min-width="150"
      />
      <el-table-column
        property="jobClassName"
        :label="$t('console.taskClass')"
        align="center"
        min-width="150"
      />
      <el-table-column
        property="createBy"
        :label="$t('console.founder')"
        align="center"
        width="150"
      />
      <el-table-column
        property="createTime"
        :label="$t('console.creationTime')"
        align="center"
        min-width="150"
      >
        <template slot-scope="scope">
          <span>{{ timeFormatConversion(scope.row.createTime) }}</span>
        </template>
      </el-table-column>
      <el-table-column
        property="jobStatus"
        :label="$t('console.taskStatus')"
        align="center"
        width="100"
      >
        <template slot-scope="scope">
          <span :style="{color: showTaskStatusColor(scope.row.jobStatus)}">
            {{ showTaskStatus(scope.row.jobStatus) }}
          </span>
        </template>
      </el-table-column>
      <el-table-column
        :label="$t('common.operate')"
        align="center"
        width="470"
      >
        <template slot-scope="scope">
          <el-button
            v-haspermi="['bxy:timingtaskmanager:start']"
            icon="el-icon-video-play"
            class="oprate"
            size="mini"
            type="success"
            @click.native="startTask(scope.row)"
          >{{ $t('console.startUp') }}</el-button>
          <el-button
            v-haspermi="['bxy:timingtaskmanager:stop']"
            icon="el-icon-video-pause"
            class="oprate"
            size="mini"
            type="warning"
            @click.native="pauseTask(scope.row)"
          >{{ $t('console.suspend') }}</el-button>
          <el-button
            v-haspermi="['bxy:timingtaskmanager:edit']"
            icon="el-icon-edit"
            class="oprate editIcon"
            size="mini"
            type="primary"
            @click.native="editTask(scope.row)"
          >{{ $t('console.modify') }}</el-button>
          <el-button
            v-haspermi="['bxy:timingtaskmanager:details']"
            class="oprate"
            size="mini"
            type="primary"
            @click.native="taskDetails(scope.row)"
          >{{ $t('console.details') }}</el-button>
          <!-- TODO (YKX) 暂时不使用删除 -->
          <!-- <el-button
            class="oprate"
            size="mini"
            type="danger"
          >{{ $t('console.delete') }}</el-button> -->
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页 -->
    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="search.page"
      :limit.sync="search.size"
      @pagination="pagination"
    />
    <!-- 新增或者修改定时任务 -->
    <div>
      <el-dialog
        :visible.sync="timingtaskFormVisible"
        @close="closeTask"
      >
        <div slot="title" style="text-align:center">{{ taskTitle }}</div>
        <el-form ref="form" :model="form" :rules="rules" label-width="100px">
          <el-form-item :label="$t('console.taskName')" prop="taskName">
            <el-input v-model="form.taskName" :disabled="showTask" :placeholder="$t('console.enterTaskname')" />
          </el-form-item>
          <el-form-item :label="$t('console.taskClass')" prop="taskClass">
            <el-select v-model="form.taskClass" :disabled="showTask" :placeholder="$t('console.selectTaskClass')">
              <el-option
                v-for="item in taskClassOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
          <!-- 同步方式 -->
          <el-form-item :label="$t('console.expression')" prop="expression">
            <el-radio-group v-model="expression">
              <el-radio :label="1">{{ $t('console.syncDay') }}</el-radio>
              <el-radio :label="2">{{ $t('console.syncWeek') }}</el-radio>
              <el-radio :label="3">{{ $t('console.syncMonth') }}</el-radio>
            </el-radio-group>
            <!-- 每周几同步 -->
            <el-checkbox-group v-show="expression === 2" v-model="checkedWeek">
              <el-checkbox
                v-for="weekDay in weeks"
                :key="weekDay.value"
                :label="weekDay.value"
                :value="weekDay.value"
              >
                {{ weekDay.label }}
              </el-checkbox>
            </el-checkbox-group>
            <!-- 每月几号同步 -->
            <el-select
              v-show="expression === 3"
              v-model="monthDates"
              :placeholder="$t('console.selectDate')"
              multiple
            >
              <el-option
                v-for="item in MonthOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
            <!-- 每日同步 -->
            <el-form-item v-show="expression !== 0">
              <span>{{ $t('console.syncTime') }}：</span>
              <el-time-picker
                v-model="dayTime"
                :placeholder="$t('console.selectSynchronizationTime')"
                value-format="HH:mm:ss"
              />
            </el-form-item>
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button @click="cancelForm('form')">
            {{ $t('common.cancel') }}
          </el-button>
          <el-button type="primary" @click.native="submitForm('form')">
            {{ $t('common.sure') }}
          </el-button>
        </div>
      </el-dialog>
      <!-- 详情弹窗 -->
      <el-dialog
        :title="$t('console.timingTaskDetails')"
        align="center"
        :visible.sync="taskDetailsVisible"
        width="630px"
        class="dialog"
      >
        <div class="detail-content">
          <div class="detail">
            <span class="detail-items">{{ $t('console.taskName') }}:</span>
            <span>{{ taskDetailsData.jobName }}</span>
          </div>
          <div class="detail">
            <span class="detail-items">{{ $t('console.taskClass') }}:</span>
            <span>{{ taskDetailsData.jobClassName }}</span>
          </div>
          <div class="detail">
            <span class="detail-items">{{ $t('console.expression') }}:</span>
            <span v-if="expression === 1">
              {{ $t('console.everyDay') }} {{ dayTime }} {{ $t('console.sync') }}
            </span>
            <span v-else-if="expression === 2">
              {{ $t('console.everyWeek') }}{{ everyWeekData.join() }}
              {{ dayTime }} {{ $t('console.sync') }}
            </span>
            <span v-else>
              {{ $t('console.everyMonth') }}{{ monthDates.join() }}{{ $t('console.date') }}
              {{ dayTime }} {{ $t('console.sync') }}
            </span>
          </div>
          <div class="detail">
            <span class="detail-items">{{ $t('console.founder') }}:</span>
            <span>{{ taskDetailsData.createBy }}</span>
          </div>
          <div class="detail">
            <span class="detail-items">{{ $t('console.creationTime') }}:</span>
            <span>{{ timeFormatConversion(taskDetailsData.createTime) }}</span>
          </div>
          <div class="detail">
            <span class="detail-items">{{ $t('console.taskStatus') }}:</span>
            <span>{{ showTaskStatus(taskDetailsData.jobStatus) }}</span>
          </div>
        </div>
        <span slot="footer" class="dialog-footer">
          <el-button type="primary" @click="taskDetailsVisible = false">
            {{ $t('common.sure') }}
          </el-button>
        </span>
      </el-dialog>
    </div>
  </div>
</template>

<script>
import log from '@/api/console';
import Pagination from '@/components/Pagination';
import { trim } from '@/utils/';

export default {
  name: 'TimingTaskManager',
  components: { Pagination },
  data() {
    return {
      search: {
        jobName: '',
        page: 1,
        size: 10,
      },
      tasks: [],
      total: 0,
      timingtaskFormVisible: false,
      taskDetailsVisible: false,
      taskTitle: '',
      form: {
        cron: '',
      },
      rules: {
        taskName: [
          { required: true, message: this.$t('console.enterTaskname'), trigger: 'blur' },
        ],
        taskClass: [
          { required: true, message: this.$t('console.selectTaskClass'), trigger: 'change' },
        ],
      },
      taskClassOptions: [],
      expression: 1, // 1 每日同步, 2 每周几同步, 3 每月几号同步
      dayTime: '23:59:59',
      weeks: [],
      checkedWeek: [],
      monthDates: [],
      MonthOptions: [],
      showTask: false,
      taskDetailsData: {},
      everyWeekData: [],
    };
  },
  watch: {
    '$i18n.locale': {
      handler(newVal, oldVal) {
        this.weeksFun();
      },
    },
  },
  created() {
    this.getTimingTasks();
    this.weeksFun();
    this.monthFun();
  },
  methods: {
    // 周几数组
    weeksFun() {
      this.weeks = [
        { label: this.$t('console.one'), value: 'MON' },
        { label: this.$t('console.two'), value: 'TUE' },
        { label: this.$t('console.three'), value: 'WED' },
        { label: this.$t('console.four'), value: 'THU' },
        { label: this.$t('console.five'), value: 'FRI' },
        { label: this.$t('console.six'), value: 'SAT' },
        { label: this.$t('console.seven'), value: 'SUN' },
      ];
    },
    // 每月几号数组
    monthFun() {
      for (let i = 1; i <= 28; i++) {
        this.MonthOptions.push(
          {
            label: i,
            value: i,
          }
        );
      }
    },
    // 获取定时任务列表
    async getTimingTasks() {
      const res = await log.getTimingTasks(this.search);
      this.tasks = res.data;
      this.total = Number(res.headers['x-total-count']);
    },
    // 时间格式转换
    timeFormatConversion(time) {
      const strArr = new Date(time);
      return this.$moment(strArr).format(
        'YYYY-MM-DD HH:mm:ss'
      );
    },
    // 展示任务状态
    showTaskStatus(status) {
      switch (status) {
        case 'START':
          return this.$t('console.onGoing');
        case 'PAUSE':
          return this.$t('console.suspend');
        case 'STOP':
          return this.$t('console.complete');
        default:
          return '';
      }
    },
    // 展示状态颜色
    showTaskStatusColor(color) {
      switch (color) {
        case 'START':
          return '#409eff';
        case 'PAUSE':
          return '#cf9236';
        case 'STOP':
          return '#5daf34';
        default:
          return '';
      }
    },
    // TODO (YKX) 新增定时任务暂时不用
    newAdd() {
      this.timingtaskFormVisible = true;
      this.taskTitle = this.$t('console.newAddTask');
    },
    // 启动定时任务
    startTask(task) {
      log.startTimingTask(task.id).then(res => {
        if (res.data) {
          this.$message({
            message: this.$t('console.taskProgress'),
            type: 'success',
          });
          this.tasks.forEach(item => {
            if (item.id === res.data.id) {
              item.jobStatus = res.data.jobStatus;
            }
          });
        }
      });
    },
    // 暂停定时任务
    pauseTask(task) {
      log.pauseTimingTask(task.id).then(res => {
        if (res.data) {
          this.$message({
            message: this.$t('console.taskSuspend'),
            type: 'info',
          });
          this.tasks.forEach(item => {
            if (item.id === res.data.id) {
              item.jobStatus = res.data.jobStatus;
            }
          });
        }
      });
    },
    // 编辑定时任务
    editTask(task) {
      this.timingtaskFormVisible = true;
      this.showTask = true;
      this.taskTitle = this.$t('console.editTask');
      this.form.taskName = task.jobName;
      this.form.taskClass = task.jobClassName;
      this.form.id = task.id;
      this.syncModeEcho(task.cronExpression);
    },
    // 同步方式回显
    syncModeEcho(str) {
      const strArr = str.split(' ');
      if (Number(strArr[2]) <= 9) {
        strArr[2] = '0' + strArr[2];
      }
      if (Number(strArr[1]) <= 9) {
        strArr[1] = '0' + strArr[1];
      }
      if (Number(strArr[0]) <= 9) {
        strArr[0] = '0' + strArr[0];
      }
      this.dayTime = `${strArr[2]}:${strArr[1]}:${strArr[0]}`;
      // 每天同步回显
      if (strArr[5] === '?' && strArr[3] === '*') {
        this.expression = 1;
      }
      // 每周几同步回显
      if (strArr[5] !== '?') {
        this.expression = 2;
        this.checkedWeek = strArr[5].split(',');
        this.everyWeekFun(this.checkedWeek);
      }
      // 每月几号同步回显
      if (strArr[3] !== '*' && strArr[3] !== '?') {
        this.expression = 3;
        this.monthDates = strArr[3].split(',').sort();
      }
    },
    // 回显每周对应的周几
    everyWeekFun(dataList) {
      const arr = [];
      this.everyWeekData = [];
      dataList.forEach(item => {
        switch (item) {
          case 'MON':
            arr.push({ index: 1, value: this.$t('console.one') });
            break;
          case 'TUE':
            arr.push({ index: 2, value: this.$t('console.two') });
            break;
          case 'WED':
            arr.push({ index: 3, value: this.$t('console.three') });
            break;
          case 'THU':
            arr.push({ index: 4, value: this.$t('console.four') });
            break;
          case 'FRI':
            arr.push({ index: 5, value: this.$t('console.five') });
            break;
          case 'SAT':
            arr.push({ index: 6, value: this.$t('console.six') });
            break;
          case 'SUN':
            arr.push({ index: 7, value: this.$t('console.ri') });
            break;
        }
      });
      arr.sort((a, b) => {
        return a.index - b.index;
      });
      arr.forEach(item => {
        this.everyWeekData.push(item.value);
      });
    },
    // 取消定时任务
    cancelForm(formName) {
      this.timingtaskFormVisible = false;
      this.$refs[formName].resetFields();
    },
    // 关闭任务弹窗
    closeTask(val) {
      this.$refs['form'].resetFields();
      this.dayTime = '23:59:59';
      this.expression = 1;
      this.checkedWeek = [];
      this.monthDates = [];
    },
    // 创建定时任务
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          this.taskMode();
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    },
    // 选择同步方式
    taskMode() {
      this.timingtaskFormVisible = false;
      let cron = '';
      if (!this.dayTime) {
        this.$message({
          message: this.$t('console.selectSynchronizationTime'),
          type: 'warning',
        });
        return;
      }
      const timeDate = this.dayTime.split(':');
      switch (this.expression) {
        case 0:
          cron = '';
          break;
        case 1:
          cron = `${timeDate[2]} ${timeDate[1]} ${timeDate[0]} * * ?`;
          break;
        case 2:
          if (this.checkedWeek.length === 0) {
            this.$message({
              message: this.$t('console.noSelectWeek'),
              type: 'warning',
            });
            return;
          }
          cron =
              `${timeDate[2]
              } ${
                timeDate[1]
              } ${
                timeDate[0]
              } ? * ${
                this.checkedWeek.join(',')}`;
          break;
        case 3:
          if (this.monthDates.length === 0) {
            this.$message({
              message: this.$t('console.noSelectDay'),
              type: 'warning',
            });
            return;
          }
          cron =
                `${timeDate[2]
                } ${
                  timeDate[1]
                } ${
                  timeDate[0]
                } ${
                  this.monthDates.join(',')
                } * ?`;
          break;
        default:
          break;
      }
      this.form.cron = cron;
      this.updateTimingTask(this.form);
    },
    // 更新定时任务的配置
    async updateTimingTask(form) {
      const params = {
        cronExpression: form.cron,
      };
      const res = await log.updateTimingTaskConfigure(params, form.id);
      if (res.data) {
        this.$message({
          message: this.$t('console.taskUpdateSuccess'),
          type: 'success',
        });
        this.getTimingTasks();
      }
    },
    // 打开任务详情
    taskDetails(task) {
      this.taskDetailsVisible = true;
      this.getTimingTasksConfigure(task.id);
    },
    // 获取定时任务的配置
    async getTimingTasksConfigure(id) {
      const res = await log.getTimingTasksConfigure(id);
      this.syncModeEcho(res.data.cronExpression);
      this.taskDetailsData = res.data;
    },
    pagination() {
      this.getTimingTasks();
    },
    /**
     * 去除两端空格处理
     * @param {String} name 输入框名称
     */
    trim(name) {
      this.search[name] = trim(this.search[name]);
    },
    /**
     * 失去焦点
     * @param {DOMEvent} event 当前输入框
     */
    blurRule(event) {
      // 输入框失去焦点操作
      event.target.blur();
    },
  },
};
</script>

<style scoped>
.filter {
  display: flex;
  margin-left: 15px;
  margin-top: 15px;
  color: #333;
  font-size: 14px;
}
.filter-item {
  margin-right: 15px;
}
.filter-container .el-input {
  width: 250px;
}
.el-select {
  display: block;
}
.oprate {
  display: inline-block;
  padding: 7px 12px;
}
.editIcon {
  background: #64D9D5;
  border: 1px solid #64D9D5;
}
.detail {
  margin-top: 15px;
  font-size: 16px;
  text-align: left;
}
.detail-content {
  margin: -40px 0 0 50px;
}
.detail-items {
  display: inline-block;
  width: 110px;
  height: 20px;
  line-height: 20px;
  text-align: right;
  margin-right: 25px;
  color: #999;
}
</style>
